<template>
	<view class="LuYin" v-show="diaShow" @tap.stop="handleTapModal">
		<view :class="['MyDialog-LuYin', recordingSrc ? 'h86' : '']" @tap.stop="">
			<view class="time">{{ seconds2time(recordingTime) }}</view>
			<view class="ly-box" @tap="recording">
				<image class="ly-svg" :src="imgPath + 'createAvatar/luyin-big.svg'" mode="widthFix"></image>
			</view>
			<view class="tips-text">点击{{ recordingText }}录音</view>
			<view class="tips-text" style="color: red">{{ RecorderTips }}</view>
			<!-- <audio class="recordingPlay" :src="recordingSrc" controls v-show="recordingSrc"></audio> -->
			<view v-if="recordingSrc" class="audio-box">
				<!-- <audio class="audio" :src="page3AudioSrc" poster="https://h5.yainoo.com/static/assets/index/audio-pic.png" :name="'录音'" author="暂无" controls></audio> -->
				<view class="audio-cont">
					<view class="info">
						<view class="name">{{ recordingName || "录音文件.mp3" }}</view>
						<view class="time">{{ seconds2time(audioCurrentTime) }}/{{ seconds2time(audioDuration) }}</view>
					</view>
					<view class="btns">
						<view class="item del" @tap="delRecordingSrc">
							<image class="icon" :src="imgPath + 'index/del.svg'" mode="widthFix"></image>
						</view>
						<view class="item play" @tap="onPlayTap">
							<image class="icon" :src="imgPath + 'index/play' + (audioPlaying ? 'ing' : 'ed') + '_back.svg'" mode="widthFix"></image>
						</view>
					</view>
				</view>
				<view class="rate-box">
					<slider class="slider" :value="audioCurrentTime" :min="0" :max="audioDuration" disabled />
				</view>
			</view>
			<view class="btns-list">
				<!-- #ifdef MP-WEIXIN -->
				<view class="btn-item" @tap="wx_uploadFile" v-if="1">
					<!-- <image class="icon" src="" mode=""></image> -->
					<view class="text">本地音频</view>
				</view>
				<!-- #endif -->
				<!-- #ifdef H5 -->
				<view class="btn-item" @tap="wx_uploadFile" v-if="1">
					<!-- <image class="icon" src="" mode=""></image> -->
					<view class="text">本地音频</view>
				</view>
				<!-- #endif -->
				<!-- #ifdef APP -->
				<view class="btn-item" @tap="getFile" v-if="0">
					<!-- <image class="icon" src="" mode=""></image> -->
					<view class="text">本地音频</view>
				</view>
				<!-- #endif -->
				<view class="btn-item" style="position: absolute; top: 2vw; right: 2vw" v-if="recordingSrc" @tap="close">
					<!-- <image class="icon" src="" mode=""></image> -->
					<view class="text" style="font-size: 4.6vw">确定</view>
				</view>
			</view>
		</view>
		<!-- #ifdef H5 -->
		<RecorderCore ref="RecorderCore" v-show="0"></RecorderCore>
		<!-- #endif -->
		<uni-popup ref="tipsPopup" type="dialog">
			<uni-popup-dialog mode="base" title="温馨提示" :confirmText="'确定'" :showClose="true" @confirm="wx_uploadFile">
				<view class="tips" style="color: #000">从微信聊天记录选择{{ "音频文件" }}</view>
			</uni-popup-dialog>
		</uni-popup>
	</view>
</template>

<script>
import { tools } from "@/utils/util";
import * as api from "@/api/createVideo.js";

// #ifdef H5
import axios from "axios";
import RecorderCore from "@/components/RecorderCore/RecorderCore.vue";
//  #endif

export default {
	name: "LuYin",
	props: {
		show: {
			type: Boolean,
			default: false
		}
	},
	data() {
		return {
			imgPath: tools.imgPath,
			mediaRecorder: {
				state: ""
			},
			audioContext: null,
			audioCurrentTime: 0,
			audioDuration: 0,
			audioPlaying: false,
			recordingTimer: null,
			recordingTime: 0,
			recordingText: "开始",
			recordingSrc: "",
			recordingPlaying: false,
			recordingName: "",
			recorderManager: null,
			RecorderTips: "",
			diaShow: true,
			uploadShow: false,
			style: {
				transform: "translateY(100%)"
			},
			style2: {
				transform: "translateY(100%)"
			},
			uploadFileSize: 200,
			btnOpt: [
				// {
				//   text: "上传音频",
				//   fnName: "uploadFile"
				// },
				// {
				//   text: "视频提取",
				//   fnName: "getVideo"
				// }
			]
		};
	},
	created() {
		this.initAudioContext();
		this.initRecorderManager();
	},
	mounted() {
		// this.initHandle();
	},
	methods: {
		// 录音器初始化
		initRecorderManager() {
			this.recorderManager = uni.getRecorderManager();
			this.recorderManager.onStart((res) => {
				this.recordingText = "结束";
				console.log("this.recorderManager.onStart", res);
			});
			this.recorderManager.onPause((res) => {
				console.log("this.recorderManager.onPause", res);
			});
			this.recorderManager.onStop(async (res) => {
				console.log("this.recorderManager.onStop", res);
				// {
				// 	"duration": 6800,
				// 	"tempFilePath": "wxfile://tmp_3cac9a828e3c509cda85e2368936ecd216185b380cf12322.mp3",
				// 	"fileSize": 110340
				// }
				this.audioDuration = res.duration / 1000;
				uni.showLoading({
					title: "提交中..."
				});
				let name = "recordFile";
				let tempFilePath = res.tempFilePath;
				let ossData = await api.postOSS({
					reqType: "",
					matName: name,
					payLoad: {}
				});

				let ossRes = await this.wx_getOSSApi_new(ossData, tempFilePath, name);
				uni.hideLoading();
				console.log("ossRes.src", ossRes?.src);
				this.recordingText = "开始";
				if (ossRes?.src) {
					this.recordingSrc = ossRes.src;
					this.audioContext.src = ossRes.src;
				}
			});
			this.recorderManager.onFrameRecorded((res) => {
				console.log("this.recorderManager.onFrameRecorded", res);
			});
			this.recorderManager.onError((res) => {
				console.log("this.recorderManager.onError", res);
				tools.easyToast(res.errMsg);
				if (this.recordingTimer) {
					clearInterval(this.recordingTimer);
					this.recordingTimer = null;
				}
			});
		},
		// 音频播放器初始化
		initAudioContext() {
			this.audioContext = uni.createInnerAudioContext();
			this.audioContext.onCanplay((res) => {
				if (!this.audioContext.duration || this.audioContext.duration == Infinity) {
					let tempCtx = uni.createInnerAudioContext();
					tempCtx.volume = 0;
					tempCtx.autoplay = true;
					tempCtx.src = this.audioContext.src;
					tempCtx.onTimeUpdate((ctxres) => {
						console.log("tempCtx.onTimeUpdate", tempCtx.duration, ctxres);
						if (tempCtx.duration && tempCtx.duration != Infinity) {
							console.log("tempCtx.onCanplay1-1", tempCtx.duration);
							this.audioDuration = tempCtx.duration;
							tempCtx.stop();
						} else {
							console.log("tempCtx.onCanplay1-2", tempCtx.duration);
						}
					});
					tempCtx.onStop(() => {
						tempCtx.destroy();
					});
					tempCtx.onEnded(() => {
						tempCtx.destroy();
					});
				} else {
					console.log("this.audioContext.onCanplay2", this.audioContext.duration);
					this.audioDuration = this.audioContext.duration;
				}
			});
			this.audioContext.onPlay((res) => {
				this.audioPlaying = true;
				console.log("this.audioContext.onPlay", res);
			});
			this.audioContext.onPause((res) => {
				this.audioPlaying = false;
				console.log("this.audioContext.onPause", res);
			});
			this.audioContext.onEnded((res) => {
				this.audioPlaying = false;
				this.audioContext.seek(0);
				this.audioCurrentTime = 0;
				console.log("this.audioContext.onEnded", res);
			});
			this.audioContext.onStop((res) => {
				this.audioPlaying = false;
				this.audioContext.seek(0);
				this.audioCurrentTime = 0;
				console.log("this.audioContext.onStop", res);
			});
			this.audioContext.onSeeking((res) => {
				console.log("this.audioContext.onSeeking", this.audioContext.currentTime);
			});
			this.audioContext.onTimeUpdate((res) => {
				this.audioCurrentTime = this.audioContext.currentTime;
				console.log("this.audioContext.onTimeUpdate", this.audioContext.currentTime);
			});
		},
		// 事件初始化
		initHandle() {
			const that = this;
			document.querySelector(".MyDialog-LuYin").ontransitionend = function (evnet) {
				let result = evnet.target.style?.transform?.match(/translateY\((.*)\)/);
				if (!that.uploadShow && result && result[1] == "100%") {
					that.diaShow = false;
				}
			};
			let recordingPlay = document.querySelector(".recordingPlay audio");
			recordingPlay.ondurationchange = function (evnet) {
				console.log("ondurationchange");
				that.recordingTime = this.duration;
			};
			recordingPlay.onplay = function (evnet) {
				that.recordingPlaying = true;
			};
			recordingPlay.onpause = function (evnet) {
				that.recordingPlaying = false;
			};
			recordingPlay.onended = function (evnet) {
				that.recordingPlaying = false;
			};
		},
		// 删除
		delRecordingSrc() {
			this.recordingSrc = "";
			this.recordingTime = 0;
		},

		// 播放
		onPlayTap() {
			if (!this.audioPlaying) {
				this.audioContext.play();
			} else {
				this.audioContext.pause();
			}
		},

		// 打开上传界面
		openUploadShow() {
			this.stopPlaying();
			if (this.mediaRecorder.state == "recording") {
				this.recording();
			}
			this.uploadShow = true;
		},

		// 应用
		join() {
			this.stopPlaying();
			this.$emit("join", { src: this.recordingSrc, duration: this.audioDuration });
			this.close();
		},

		// 停止试听
		stopPlaying() {
			this.audioContext.stop();
			return;
			let recordingPlay = document.querySelector(".recordingPlay audio");
			recordingPlay.pause();
			recordingPlay.currentTime = 0;
		},

		// 录音
		async recording_H5() {
			console.log("recording_H5");
			//录音
			const that = this;

			if (that.recordingPlaying) {
				this.stopPlaying();
			}
			if (that.mediaRecorder.state != "recording") {
				this.RecorderTips = "";
				//开始录音
				let flag = await that.$refs.RecorderCore.recStart();
				if (!flag) {
					console.log(that.$refs.RecorderCore.logs);
					this.RecorderTips = that.$refs.RecorderCore.logs[0].msg;

					this.RecorderTipsShow = true;
					this.mediaRecorder.state = "";
					return;
				}
				let nowTime = new Date().getTime();
				that.recordingTimer = setInterval(() => {
					that.recordingTime = (new Date().getTime() - nowTime) / 1000;

					// that.recordingTime = tools.seconds2time(that.$refs.RecorderCore.duration / 1000);
				}, 1000 / 60);
				that.mediaRecorder.state = "recording";
				that.recordingText = "结束";
			} else {
				//停止录音
				let flag = await that.$refs.RecorderCore.recStop();
				if (!flag) return;
				clearInterval(that.recordingTimer);
				that.recordingTimer = null;
				that.mediaRecorder.state = "";
				that.recordingText = "开始";
				that.audioDuration = that.recordingTime;
				let blob = this.$refs.RecorderCore.logs[0].res.blob;
				let tempSrc = URL.createObjectURL(blob);
				console.log("停止录音");
				let matterValue = await tools.setVideoSrc(tempSrc);
				let name = new Date().getTime();
				let fileOfBlob = new File([blob], name, {
					type: "audio/wav"
				});
				let ossData = await api.postOSS({
					reqType: "mat_audio",
					matName: name,
					payLoad: { matterValue: matterValue }
				});
				let res = await this.getOSSApi_new(ossData, fileOfBlob, name);
				console.log(res);
				// let res = await that.getOSSApi(fileOfBlob, name);
				if (res?.src) {
					that.recordingSrc = res.src;
					that.audioContext.src = res.src;
				} else {
					that.recordingSrc = "";
					that.audioContext.src = "";
				}
			}
		},

		// 录音
		async recording() {
			// #ifdef H5
			this.recording_H5();
			return;
			//  #endif
			const that = this;
			if (!that.recordingTimer) {
				let next = await new Promise(async (next) => {
					// #ifdef APP
					let statusCode = await tools.app_permision.requestAndroidPermission("android.permission.RECORD_AUDIO");
					next(statusCode == 1);
					// #endif
					// #ifdef MP-WEIXIN
					uni.authorize({
						scope: "scope.record",
						success() {
							next(true);
						},
						fail() {
							next(false);
						}
					});
					// #endif
					// #ifdef H5
					next(true);
					// #endif
				});
				if (!next) {
					tools.easyToast("未授权录音！");
					return;
				}
				this.recordingText = "结束";
				//开始录音
				const start = Date.now();
				that.recordingSrc = "";
				that.audioDuration = 0;
				that.recordingTimer = setInterval(() => {
					const millis = Date.now() - start;
					// console.log(`seconds elapsed = ${Math.floor(millis / 1000)}`)
					that.recordingTime = millis / 1000;
					// expected output: seconds elapsed = 2
				}, 1000 / 60);
				that.recorderManager.start({
					duration: 60000,
					format: "mp3",
					sampleRate: 22050,
					numberOfChannels: 1,
					encodeBitRate: 124000,
					frameSize: 50
				});
			} else {
				this.recordingText = "开始";
				that.recorderManager.stop();
				clearInterval(that.recordingTimer);
				that.recordingTimer = null;
			}
		},
		// 动态事件
		dynamicEvents(fnName) {
			if (tools.myTypeOf(this[fnName]) == "Function") {
				this[fnName]();
			} else {
				throw `${fnName}不是一个函数`;
			}
		},
		// wx小程序上传音频
		async wx_uploadFile() {
			const that = this;
			let extension = ["wav", "mp3", "aac", "m4a", "ogg", "3gpp"];
			extension = extension.reduce((p, e) => {
				p.push(e);
				p.push(e.toLocaleUpperCase());
				return p;
			}, []);

			let res = await new Promise((next) => {
				// #ifdef H5
				uni.chooseFile({
					count: 1, //默认100
					extension: extension,
					success: function (res) {
						next(res);
					},
					fail(err) {
						console.error(err);
						next(null);
					}
				});
				// #endif

				// #ifdef MP-WEIXIN
				uni.chooseMessageFile({
					count: 1, //默认100
					type: "file",
					extension: extension,
					success: async (res) => {
						next(res);
					},
					fail(err) {
						console.error(err);
						next(null);
					}
				});
				// #endif
			});
			if (!res) return;

			let file = res.tempFiles[0];
			console.log("选择音频文件", res);
			// {
			// 	"errMsg": "chooseMessageFile:ok",
			// 	"tempFiles": [{
			// 		"path": "wxfile://tmp_31dc92a076e8445ad5c1157cffed8ced9d583501207d8e07.mp3",
			// 		"name": "Go_Beyond_Andy.mp3",
			// 		"size": 10286911,
			// 		"type": "file",
			// 		"time": 1716533118,
			// 	}],
			// }
			that.recordingName = file.name;
			let condition = extension.some((e) => file.name.includes(e));
			if (!condition) {
				return tools.easyToast("请选择音频文件！");
			}
			let name = file.name.replace(/[^\u4e00-\u9fa5a-zA-Z0-9\.]+/g, "");
			// if (!/^[\u4e00-\u9fa5a-zA-Z0-9\.\-]+$/.test(name)) {
			// 	return tools.easyToast("文件名不能包含符号，只能是文字或数字");
			// }
			if (file.size / 1024 / 1024 > that.uploadFileSize) {
				return tools.easyToast(`文件大小超过${that.uploadFileSize}M!`);
			}
			let ossData = await api.postOSS({
				reqType: "",
				matName: name,
				payLoad: {}
			});
			let ossRes = await that.wx_getOSSApi_new(ossData, file.path, name);
			if (!ossRes) {
				tools.easyToast("上传失败！");
				return;
			}
			console.log("上传音频", ossRes);
			that.recordingSrc = ossRes.src;
			that.audioContext.src = ossRes.src;
		},
		// wx小程序oss上传文件
		wx_getOSSApi_new(ossData, file, name) {
			const that = this;
			let res = ossData;
			function getUUID() {
				let keyStr = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
				keyStr = "xxxxxxxx-6xxx";
				return keyStr.replace(/[xy]/g, (c) => {
					return (c === "x" ? (Math.random() * 16) | 0 : "r&0x3" | "0x8").toString(16);
				});
			}
			let url_name = "https://alleymall.oss-cn-guangzhou.aliyuncs.com";
			let key = res.data.dir + "/" + getUUID() + name;
			return new Promise((next) => {
				uni.uploadFile({
					url: url_name,
					filePath: file,
					name: "file",
					formData: {
						policy: res.data.policy,
						signature: res.data.signature,
						ossaccessKeyId: res.data.accessid,
						key: key,
						dir: res.data.dir,
						host: res.data.host,
						expire: res.data.expire,
						callback: res.data.callback
					},
					success: (uploadFileRes) => {
						let src = url_name + "/" + key;
						// console.log(src);
						// that.audioPlayerSrc = src;
						// console.log(response);
						next({ ...uploadFileRes, src });
					}
				});
			});
		},
		//上传文件api
		async getOSSApi_new(ossData, file, name) {
			const that = this;
			let res = ossData;

			function getUUID() {
				let keyStr = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
				keyStr = "xxxxxxxx-6xxx";
				return keyStr.replace(/[xy]/g, (c) => {
					return (c === "x" ? (Math.random() * 16) | 0 : "r&0x3" | "0x8").toString(16);
				});
			}
			const formData = new FormData();
			let url_name = "https://alleymall.oss-cn-guangzhou.aliyuncs.com";
			let key = res.data.dir + "/" + getUUID() + name;
			formData.append("policy", res.data.policy);
			formData.append("signature", res.data.signature);
			formData.append("ossaccessKeyId", res.data.accessid);
			formData.append("key", key);
			formData.append("dir", res.data.dir);
			formData.append("host", res.data.host);
			formData.append("expire", res.data.expire);
			formData.append("callback", res.data.callback);
			// formData.append('type', res.data.callback)
			formData.append("file", file);

			return axios
				.post(url_name, formData, {
					headers: {
						"Content-Type": "multipart/form-data"
					}
				})
				.then((response) => {
					let src = url_name + "/" + key;
					// console.log(src);
					// that.audioPlayerSrc = src;
					// console.log(response);
					return {
						...response,
						src
					};
				})
				.catch((error) => {
					console.log(error);
				});
		},

		// 视频提取
		getVideo() {
			console.log("视频提取");
			tools.easyToast("暂未开放！");
		},
		// 关闭录音界面
		close() {
			this.stopPlaying();
			if (this.mediaRecorder.state == "recording") {
				this.recording();
			}
			this.$emit("close");
		},
		// 关闭音频上传界面
		close2() {
			this.uploadShow = false;
			this.style.transform = `translateY(0%)`;
		},
		// 监听遮罩层tap事件
		handleTapModal() {
			if (this.uploadShow) {
				this.close2();
			} else {
				this.close();
			}
		}
	},
	watch: {
		show: {
			handler(val) {
				if (val) {
				} else {
					this.join();
				}
			}
		},
		uploadShow: {
			handler(val) {
				if (val) {
					setTimeout(() => {
						this.style2.transform = `translateY(0%)`;
						this.style.transform = `translateY(100%)`;
					}, 168);
				} else {
					this.style2.transform = `translateY(100%)`;
				}
			}
		}
	},
	computed: {
		// 秒数转时间
		seconds2time() {
			return (index_num) => {
				// tools.seconds2time;
				if (!index_num) return "00:00:00.00";
				// let getHours = (parseInt(index_num / 60 / 60) % 12).toString().padStart(2, 0);
				// let getMinutes = (parseInt(index_num / 60)% 60).toString().padStart(2, 0);
				let getMinutes = parseInt(index_num / 60)
					.toString()
					.padStart(2, 0);
				let getSeconds = (index_num % 60).toFixed(2);
				if (getSeconds < 10) getSeconds = "0" + getSeconds;
				// let str = `${getHours}.${getMinutes}.${getSeconds}`;
				let str = `${getMinutes}:${getSeconds}`;
				return str;
			};
		}
	},
	components: {
		// #ifdef H5
		RecorderCore
		// #endif
	}
};
</script>

<style lang="scss">
.LuYin {
	width: 100%;
	height: auto;
	position: relative;
	// overflow: hidden;
	// position: absolute;
	// left: 0vw;
	// right: 0vw;
	// background: rgba(0, 0, 0, 0.68);
	z-index: 106;

	.close {
		position: absolute;
		top: 2vw;
		right: 2vw;
	}

	.MyDialog-LuYin {
		width: 100%;
		// position: absolute;
		bottom: 0vw;
		background: #fff;
		color: #000;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		padding: 6vw 2vw;
		padding-top: 2vw;
		box-sizing: border-box;
		border-radius: 2.5vw 2.5vw 0vw 0vw;
		// transition: all 300ms;

		.time {
			margin: 2vw;
		}

		.ly-box {
			background: linear-gradient(217.51deg, rgba(0, 255, 174, 1) 0%, rgba(27, 161, 250, 1) 100%);
			padding: 2vw;
			width: 20vw;
			height: 20vw;
			border-radius: 50%;
			display: flex;
			justify-content: center;
			align-items: center;

			.ly-svg {
				width: 52%;
			}
		}

		.tips-text {
			padding: 5vw 2vw;
			font-size: 28rpx;
			color: rgba(51, 51, 51, 1);
		}

		.audio-box {
			width: 96%;
			margin: 2vw auto;
			position: relative;
			border-radius: 2.5vw;
			background: rgba(0, 0, 0, 0.86);
			display: flex;
			flex-direction: column;
			justify-content: center;
			align-items: center;
			box-sizing: border-box;
			padding: 2.5vw;

			.audio-cont {
				width: 100%;
				display: flex;
				justify-content: center;
				align-items: center;
				.info {
					flex: 1;
					font-size: 3.5vw;
					.name {
						color: #fff;
						margin-bottom: 1vw;
					}
					.time {
						color: rgba(255, 255, 255, 0.168);
					}
				}
				.btns {
					display: flex;
					justify-content: center;
					align-items: center;
					.item {
						width: 8.6vw;
						margin-right: 2vw;
						&.del {
							width: 6.8vw;
						}
						.icon {
							width: 100%;
							display: block;
						}
					}
				}
			}

			.rate-box {
				margin-top: 5vw;
				width: 100%;
			}
		}

		.btns-list {
			display: flex;
			justify-content: center;
			align-items: center;

			.btn-item {
				border-radius: 2.5vw;
				background: rgba(237, 237, 237, 1);
				display: flex;
				justify-content: center;
				align-items: center;
				padding: 1.5vw 2vw;
				margin-right: 2vw;

				&:last-child {
					margin-right: 0vw;
				}

				.text {
					font-size: 28rpx;
					color: rgba(102, 102, 102, 1);
				}
			}
		}
	}

	.MyDialog-upload {
		width: 100%;
		height: 32vw;
		position: absolute;
		bottom: 0vw;
		background: #fff;
		color: #000;
		padding: 2vw;
		padding-top: 2vw;
		box-sizing: border-box;
		border-radius: 2.5vw 2.5vw 0vw 0vw;
		// transition: all 300ms;

		.btns-list {
			box-sizing: border-box;
			padding: 2vw;
			display: flex;
			flex-direction: column;
			height: 100%;

			.item {
				flex: 1;
				display: flex;
				justify-content: center;
				align-items: center;
				border-bottom: 1px solid rgba(240, 240, 240, 1);

				&:last-child {
					border-bottom: none;
				}
			}
		}
	}
}
</style>
